package com.anniljing.kotlionlearn.Basic.coroutine

import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.channels.produce
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() {
//    testChannelDefault()
//    testChannelUnlimited()
//   testChannelConflated()
    testSendLargeData()
}

fun testChannelDefault(){
    runBlocking {
        val channel = Channel<Int>()
        launch {
            (1..3).forEach {
                channel.send(it)
                println("Send:$it,CurrentThread:${Thread.currentThread().name}")
            }
            channel.close()
        }

        launch {
            for (i in channel) {
                println("Received:$i,CurrentThread:${Thread.currentThread().name}")
            }
        }
    }
}

/**
 * 当设置 capacity = UNLIMITED 的时候，Channel 的容量是无限大的，所以发送方可以一直往管道当中塞入数据，等数据都塞完以后，接收方才开始接收
 */
fun testChannelUnlimited(){
    runBlocking {
        val channel= Channel<Int>(capacity = Channel.Factory.UNLIMITED)
        launch {
            (1..3).forEach {
                channel.send(it)
                println("Send:$it,CurrentThread:${Thread.currentThread().name}")
            }
            channel.close()
        }

        launch {
            for (i in channel) {
                println("Received:$i,CurrentThread:${Thread.currentThread().name}")
            }
        }
    }
}

/**
 * 当设置 capacity = CONFLATED 的时候，发送方也会一直发送数据，而且，对于接收方来说，它永远只能接收到最后一条数据。
 */
fun testChannelConflated(){
    runBlocking {
        val channel= Channel<Int>(capacity = Channel.Factory.CONFLATED)
        launch {
            (1..3).forEach {
                channel.send(it)
                println("Send:$it,CurrentThread:${Thread.currentThread().name}")
            }
            channel.close()
        }

        launch {
            for (i in channel) {
                println("Received:$i,CurrentThread:${Thread.currentThread().name}")
            }
        }
    }
}

fun testSendLargeData(){
    runBlocking {
        val channel:ReceiveChannel<Int> = produce(capacity = 3){
            (1..300).forEach {
                send(it)
            }
        }
        channel.consumeEach {
            println("Receive $it")
        }
    }
}